﻿
Imports osi.root.procedure
Imports osi.root.formation
Imports osi.root.utils
Imports osi.root.connector
Imports osi.service.convertor

Public Class flow_block_adapter
    Implements block

    Public ReadOnly flow_dev As flow

    Public Sub New(ByVal f As flow)
        assert(Not f Is Nothing)
        flow_dev = f
    End Sub

    Public Shared Function convert(ByVal i As flow, ByRef o As block) As Boolean
        o = New flow_block_adapter(i)
        Return True
    End Function

    Public Shared Function convert(ByVal i As flow, ByVal o As pointer(Of block)) As event_comb
        Return sync_async(Function() As Boolean
                              Dim r As block = Nothing
                              Return convert(i, r) AndAlso
                                     eva(o, r)
                          End Function)
    End Function

    Public Shared Function convert(ByVal i As block, ByRef o As flow) As Boolean
        Dim a As flow_block_adapter = Nothing
        If cast(i, a) AndAlso
           assert(Not a Is Nothing) Then
            o = a.flow_dev
            Return True
        Else
            Return False
        End If
    End Function

    Public Function receive(ByVal result As pointer(Of Byte())) As event_comb _
                           Implements block.receive
        Dim ec As event_comb = Nothing
        Dim exp_len As UInt32 = 0
        Dim r() As Byte = Nothing
        Return New event_comb(Function() As Boolean
                                  ReDim r(preamble_length - 1)
                                  ec = flow_dev.receive(r)
                                  Return waitfor(ec) AndAlso
                                         goto_next()
                              End Function,
                              Function() As Boolean
                                  If ec.end_result() AndAlso
                                     parse_as_preamble(r, exp_len) Then
                                      ReDim r(exp_len - 1)
                                      ec = flow_dev.receive(r)
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  Else
                                      Return False
                                  End If
                              End Function,
                              Function() As Boolean
                                  Return ec.end_result() AndAlso
                                         eva(result, r) AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Function send(ByVal buff() As Byte,
                         ByVal offset As UInt32,
                         ByVal count As UInt32) As event_comb _
                        Implements block.send
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  If offset + count > array_size(buff) Then
                                      Return False
                                  ElseIf count = 0 Then
                                      Return goto_end()
                                  Else
                                      ec = flow_dev.send(to_chunk(buff, offset, count))
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  End If
                              End Function,
                              Function() As Boolean
                                  Return ec.end_result() AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Function sense(ByVal pending As pointer(Of Boolean),
                          ByVal timeout_ms As Int64) As event_comb Implements block.sense
        Return flow_dev.sense(pending, timeout_ms)
    End Function
End Class
